package com.maple.excel.utils;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;

import javax.validation.ConstraintViolation;
import javax.validation.ValidationException;
import javax.validation.Validator;
import java.util.Set;

/**
 * <p>参数校验工具类</p>
 *
 * @author maple
 */
@Component
public class ValidatorUtil implements ApplicationContextAware {

    // 通过Spring获得校验器
    private static Validator validator;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        Validator validatorBean = applicationContext.getBean(Validator.class);
        setValidator(validatorBean);
    }

    public static void setValidator(Validator validatorBean) {
        // Unwrap to the native Validator with forExecutables support
        if (validatorBean instanceof LocalValidatorFactoryBean) {
            validator = ((LocalValidatorFactoryBean) validatorBean).getValidator();
        } else if (validatorBean instanceof SpringValidatorAdapter) {
            validator = validatorBean.unwrap(Validator.class);
        } else {
            validator = validatorBean;
        }
    }

    /**
     * 对配置了注解的对象进行校验
     */
    public static <T> void validate(T object) {
        Set<ConstraintViolation<T>> violationSet = validator.validate(object);
        for (ConstraintViolation<T> violation : violationSet) {
            // 快速返回第一个校验失败的数据
            throw new ValidationException(violation.getMessage());
        }
    }
}
